/**
 * @file board_info.cpp
 * @author fwy (2643660853@qq.com)
 * @brief
 * @version 0.1
 * @date 2025-08-18
 *
 * @copyright Copyright (c) 2025
 *
 */

#include "board.h"

#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
Board::Board()
{
    // socket_client_ = std::make_unique<SocketClient>();
    // serial_ = std::make_unique<Serial>("/dev/ttyS6");

    // // 打开串口
    // if (!serial_->open())
    // {
    //     throw std::runtime_error("Failed to open serial port");
    // }

    // // 配置自动重连 - 无限重试，初始延迟1秒，最大延迟30秒
    // socket_client_->setAutoReconnect(true, -1, 1000, 30000);

    // std::string client_id = "Anke2101_安科测试一店_安科测试一店男更";

    // // 设置连接状态回调
    // socket_client_->setConnectionCallback([this](bool connected)
    //                                       {
    //     if (connected) {
    //         std::cout << "已连接到服务器" << std::endl;
    //     } else {
    //         std::cout << "与服务器的连接已断开，正在尝试重连..." << std::endl;
    //     } });

    // // 设置消息回调
    // socket_client_->setMessageCallback([&, this](const std::string &message)
    //                                    {
    //     // 原有的消息处理代码...
    //     std::cout << "服务器消息: " << message << std::endl;

    //     // 简单解析JSON格式消息: {"controller_id":"1","lock_numble":"1"}
    //     std::string controller_id_key = "\"controller_id\":\"";
    //     std::string lock_numble_key = "\"lock_numble\":\"";

    //     size_t controller_pos = message.find(controller_id_key);
    //     size_t lock_pos = message.find(lock_numble_key);

    //     if (controller_pos != std::string::npos && lock_pos != std::string::npos) {
    //         // 解析逻辑...
    //         controller_pos += controller_id_key.length();
    //         lock_pos += lock_numble_key.length();

    //         size_t controller_end = message.find("\"", controller_pos);
    //         size_t lock_end = message.find("\"", lock_pos);

    //         if (controller_end != std::string::npos && lock_end != std::string::npos) {
    //             std::string controller_id_str = message.substr(controller_pos, controller_end - controller_pos);
    //             std::string lock_id_str = message.substr(lock_pos, lock_end - lock_pos);

    //             try {
    //                 int controller_id = std::stoi(controller_id_str);
    //                 int lock_id = std::stoi(lock_id_str);

    //                 std::cout << "开锁请求: 控制板 " << controller_id << ", 锁号 " << lock_id << std::endl;

    //                 // 调用开锁函数
    //                 bool result = serial_->openLock(controller_id, lock_id);
    //                 if (result) {
    //                     std::cout << "成功打开锁 " << lock_id << " 在控制板 " << controller_id << std::endl;
    //                 } else {
    //                     std::cerr << "打开锁 " << lock_id << " 在控制板 " << controller_id << " 失败" << std::endl;
    //                 }
    //             } catch (const std::exception &e) {
    //                 std::cerr << "转换ID为整数时出错: " << e.what() << std::endl;
    //             }
    //         }
    //     } else {
    //         std::cerr << "无效的消息格式" << std::endl;
    //     } });

    http_client_ = std::make_unique<HttpClient>("8.152.4.127", 443);
    http_client_->setDefaultHeaders({{"User-Agent", "MyHttpsClient/1.0"},
                                     {"Accept", "application/json"}});
    http_client_->enable_server_certificate_verification(false);
    http_client_->setTimeout(5);
    http_client_->setFollowRedirect(true);
}

Lock Board::httpDistributeLock(const std::string &brand_code, const std::string &organization,
                               const std::string &zone, const std::string &phone, const std::string &type, const std::string &layer)
{
    // 构造请求路径
    std::string path = "/cabinet/locks/distribute";

    // 构造请求体JSON
    std::string body = "{";
    body += "\"brand_code\": \"" + brand_code + "\",";
    body += "\"organization\": \"" + organization + "\",";
    body += "\"zone\": \"" + zone + "\",";
    body += "\"phone\": \"" + phone + "\",";
    body += "\"type\": \"" + type + "\"";
    body += ",\"layer\": \"" + layer + "\"";
    body += "}";

    // 发送POST请求
    auto res = http_client_->post(path, body, "application/json");

    Lock lock;

    if (res.ok && res.status == 200)
    {
        std::cout << "[httpDistributeLock] POST 状态码: " << res.status << std::endl;
        std::cout << "[httpDistributeLock] POST 响应体: " << res.body << std::endl;

        // 解析JSON响应
        std::string response = res.body;

        // 提取JSON字段的辅助函数
        auto parseJsonField = [&response](const std::string &fieldName) -> std::string
        {
            std::string pattern = "\"" + fieldName + "\":\"";
            size_t start = response.find(pattern);
            if (start == std::string::npos)
            {
                return "";
            }
            start += pattern.length();
            size_t end = response.find("\"", start);
            if (end == std::string::npos)
            {
                return "";
            }
            return response.substr(start, end - start);
        };

        // 填充Lock结构体的所有字段
        lock.brand_code = parseJsonField("brand_code");
        lock.collect_time = parseJsonField("collect_time");
        lock.controller_id = parseJsonField("controller_id");
        lock.lock = parseJsonField("lock");
        lock.lock_numble = parseJsonField("lock_numble");
        lock.organization = parseJsonField("organization");
        lock.person = parseJsonField("person");
        lock.phone = parseJsonField("phone");
        lock.status = parseJsonField("status");
        lock.type = parseJsonField("type");
        lock.use_time = parseJsonField("use_time");
        lock.zone = parseJsonField("zone");
        lock.layer = parseJsonField("layer");
        lock.cabinet_number = parseJsonField("cabinet_number");
        lock.effective_time = parseJsonField("effective_time");

        // 打印提取的关键信息
        std::cout << "分配成功：控制器ID=" << lock.controller_id
                  << ", 柜号=" << lock.lock_numble
                  << ", 状态=" << lock.status << std::endl;

        return lock;
    }
    else
    {
        std::cerr << "分配柜子失败: " << res.error << ", 状态码: " << res.status << std::endl;
        // 设置错误状态
        lock.status = "error";
        lock.lock = "error";
        return lock;
    }
}

bool Board::loadDeviceConfig()
{
    QFile file("device_config.txt");
    if (!file.exists())
    {
        std::cerr << "设备配置文件不存在!" << std::endl;
        return false;
    }

    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        std::cerr << "无法打开设备配置文件!" << std::endl;
        return false;
    }

    QTextStream in(&file);
    QMap<QString, QString> configMap;

    // 逐行读取配置
    while (!in.atEnd())
    {
        QString line = in.readLine();
        int separatorPos = line.indexOf('=');
        if (separatorPos > 0)
        {
            QString key = line.left(separatorPos);
            QString value = line.mid(separatorPos + 1);
            configMap[key] = value;
        }
    }
    file.close();

    // 填充配置对象
    deviceConfig.brand_code = configMap.value("brand_code");
    deviceConfig.organization = configMap.value("store_name");
    deviceConfig.zone = configMap.value("zone");
    deviceConfig.sn_code = configMap.value("sn_code");
    deviceConfig.device_type = configMap.value("device_type");

    std::cout << "已加载设备配置：" << std::endl
              << "品牌代码: " << deviceConfig.brand_code.toStdString() << std::endl
              << "门店名称: " << deviceConfig.organization.toStdString() << std::endl
              << "管理区: " << deviceConfig.zone.toStdString() << std::endl;

    return true;
}

std::string Board::httpGetPersonPasswd(const std::string &brand_code, const std::string &organization,
                                       const std::string &zone, const std::string &phone)
{
    // 拼接带Query参数的路径
    std::string path = "/cabinet/persons/query?brand_code=" + brand_code + "&organization=" + organization + "&phone=" + phone;

    auto res = http_client_->get(path);
    if (res.ok)
    {
        std::cout << "[httpGetPersonPasswd] POST 状态码: " << res.status << std::endl;
        std::cout << "[httpGetPersonPasswd] POST 响应体: " << res.body << std::endl;

        // 解析JSON获取passwd字段
        std::string response = res.body;
        std::string passwd_key = "\"passwd\":\"";
        size_t passwd_pos = response.find(passwd_key);

        if (passwd_pos != std::string::npos)
        {
            passwd_pos += passwd_key.length(); // 跳过键名部分
            size_t passwd_end = response.find("\"", passwd_pos);

            if (passwd_end != std::string::npos)
            {
                std::string passwd = response.substr(passwd_pos, passwd_end - passwd_pos);
                std::cout << "找到密码: " << passwd << std::endl;
                return passwd;
            }
        }

        std::cerr << "在响应中未找到密码字段" << std::endl;
        return "";
    }
    else
    {
        std::cerr << "[httpGetPersonPasswd] GET 错误: " << res.error << std::endl;
        return "";
    }
}

Lock Board::httpQueryLock(const std::string &brand_code, const std::string &organization,
                          const std::string &zone, const std::string &phone, const std::string &type)
{
    // 拼接带Query参数的路径
    std::string path = "/cabinet/locks/query?brand_code=" + brand_code +
                       "&organization=" + organization +
                       "&zone=" + zone +
                       "&phone=" + phone +
                       "&type=" + type;

    auto res = http_client_->get(path);

    Lock lock; // 初始化空的Lock结构体

    if (res.ok && res.status == 200)
    {
        std::cout << "[httpQueryLock] GET 状态码: " << res.status << std::endl;
        std::cout << "[httpQueryLock] GET 响应体: " << res.body << std::endl;

        // 解析JSON响应
        std::string response = res.body;

        // 提取JSON字段的辅助函数
        auto parseJsonField = [&response](const std::string &fieldName) -> std::string
        {
            std::string pattern = "\"" + fieldName + "\":\"";
            size_t start = response.find(pattern);
            if (start == std::string::npos)
            {
                return "";
            }
            start += pattern.length();
            size_t end = response.find("\"", start);
            if (end == std::string::npos)
            {
                return "";
            }
            return response.substr(start, end - start);
        };

        // 填充Lock结构体的所有字段
        lock.brand_code = parseJsonField("brand_code");
        lock.collect_time = parseJsonField("collect_time");
        lock.controller_id = parseJsonField("controller_id");
        lock.lock = parseJsonField("lock");
        lock.lock_numble = parseJsonField("lock_numble");
        lock.organization = parseJsonField("organization");
        lock.person = parseJsonField("person");
        lock.phone = parseJsonField("phone");
        lock.status = parseJsonField("status");
        lock.type = parseJsonField("type");
        lock.use_time = parseJsonField("use_time");
        lock.layer = parseJsonField("layer");
        lock.cabinet_number = parseJsonField("cabinet_number");
        lock.effective_time = parseJsonField("effective_time");

        // 打印查询到的关键信息
        if (!lock.controller_id.empty() && !lock.lock_numble.empty())
        {
            std::cout << "查询成功：控制器ID=" << lock.controller_id
                      << ", 柜号=" << lock.lock_numble
                      << ", 状态=" << lock.status << std::endl;
        }
        else
        {
            std::cout << "未查询到已分配的柜子" << std::endl;
        }
    }
    else
    {
        std::cerr << "查询柜子失败: " << res.error << ", 状态码: " << res.status << std::endl;
    }

    return lock;
}

Lock Board::httpReturnLock(const std::string &brand_code, const std::string &organization,
                           const std::string &zone, const std::string &phone, const std::string &type)
{
    std::string path = "/cabinet/locks/return";
    std::string request_body = "{"
                               "\"brand_code\":\"" +
                               brand_code + "\","
                                            "\"organization\":\"" +
                               organization + "\","
                                              "\"zone\":\"" +
                               zone + "\","
                                      "\"phone\":\"" +
                               phone + "\","
                                       "\"type\":\"" +
                               type + "\""
                                      "}";

    auto res = http_client_->post(path, request_body);

    Lock lock;

    if (res.ok && res.status == 200)
    {
        std::cout << "[httpReturnLock] POST 状态码: " << res.status << std::endl;
        std::cout << "[httpReturnLock] POST 响应体: " << res.body << std::endl;

        std::string response = res.body;

        // 提取JSON字段的辅助函数
        auto parseJsonField = [&response](const std::string &fieldName) -> std::string
        {
            std::string pattern = "\"" + fieldName + "\":\"";
            size_t start = response.find(pattern);
            if (start == std::string::npos)
            {
                return "";
            }
            start += pattern.length();
            size_t end = response.find("\"", start);
            if (end == std::string::npos)
            {
                return "";
            }
            return response.substr(start, end - start);
        };

        // 填充Lock结构体的所有字段
        lock.brand_code = parseJsonField("brand_code");
        lock.cabinet_number = parseJsonField("cabinet_number");
        lock.collect_time = parseJsonField("collect_time");
        lock.controller_id = parseJsonField("controller_id");
        lock.effective_time = parseJsonField("effective_time");
        lock.layer = parseJsonField("layer");
        lock.lock = parseJsonField("lock");
        lock.lock_numble = parseJsonField("lock_numble");
        lock.organization = parseJsonField("organization");
        lock.person = parseJsonField("person");
        lock.phone = parseJsonField("phone");
        lock.status = parseJsonField("status");
        lock.type = parseJsonField("type");
        lock.use_time = parseJsonField("use_time");
        lock.zone = parseJsonField("zone");
        lock.layer = parseJsonField("layer");
        lock.cabinet_number = parseJsonField("cabinet_number");
        lock.effective_time = parseJsonField("effective_time");

        std::cout << "退柜返回：控制器ID=" << lock.controller_id
                  << ", 柜号=" << lock.lock_numble
                  << ", 状态=" << lock.status << std::endl;
    }
    else
    {
        std::cerr << "[httpReturnLock] POST 错误: " << res.error << std::endl;
    }
    return lock;
}

int Board::httpGetAmountCabinetByLayer(const std::string &brand_code, const std::string &organization,
                                       const std::string &zone, const std::string &layer)
{
    // 构造请求路径
    std::string path = "/cabinet/locks/query?brand_code=" + brand_code +
                       "&organization=" + organization +
                       "&zone=" + zone +
                       "&layer=" + layer +
                       "&status=未使用";

    auto res = http_client_->get(path);

    if (res.ok && res.status == 200)
    {
        std::cout << "[httpGetAmountCabinetByLayer] GET 状态码: " << res.status << std::endl;
        std::cout << "[httpGetAmountCabinetByLayer] GET 响应体: " << res.body << std::endl;

        // 假设返回的是一个JSON数组，如 [{"lock_numble":"1",...}, {"lock_numble":"2",...}]
        // 简单统计 "lock_numble" 出现的次数作为柜子数量
        int count = 0;
        std::string key = "\"lock_numble\":\"";
        size_t pos = 0;
        while ((pos = res.body.find(key, pos)) != std::string::npos)
        {
            count++;
            pos += key.length();
        }
        return count;
    }
    else
    {
        std::cerr << "[httpGetAmountCabinetByLayer] GET 错误: " << res.error << ", 状态码: " << res.status << std::endl;
        return 0;
    }
}

#include <ctime>
#include <iomanip>
#include <sstream>

void Board::httpUploadLog(const std::string &brand_code, const std::string &organization,
                          const std::string &zone, const std::string &phone, const std::string &cabinet_number,
                          const std::string &cabinet_type, const std::string &action)
{
    // 获取当前时间，格式为 "YYYY-MM-DD HH:MM:SS"
    std::time_t t = std::time(nullptr);
    std::tm tm_now;
    localtime_r(&t, &tm_now);
    std::ostringstream oss;
    oss << std::put_time(&tm_now, "%Y-%m-%d %H:%M:%S");
    std::string time = oss.str();

    std::string path = "/cabinet/records/add";
    std::string body = "{";
    body += "\"brand_code\": \"" + brand_code + "\",";
    body += "\"organization\": \"" + organization + "\",";
    body += "\"zone\": \"" + zone + "\",";
    body += "\"phone\": \"" + phone + "\",";
    body += "\"cabinet_number\": \"" + cabinet_number + "\",";
    body += "\"cabinet_type\": \"" + cabinet_type + "\",";
    body += "\"action\": \"" + action + "\",";
    body += "\"time\": \"" + time + "\"";
    body += "}";

    auto res = http_client_->post(path, body, "application/json");
    if (res.ok)
    {
        std::cout << "[httpUploadLog] POST 状态码: " << res.status << std::endl;
        std::cout << "[httpUploadLog] POST 响应体: " << res.body << std::endl;
    }
    else
    {
        std::cerr << "[httpUploadLog] POST 错误: " << res.error << ", 状态码: " << res.status << std::endl;
    }
}

std::vector<Lock> Board::httpGetAllLocks(const std::string &brand_code, const std::string &organization,
                                         const std::string &zone)
{
    std::string path = "/cabinet/locks/query?brand_code=" + brand_code +
                       "&organization=" + organization +
                       "&zone=" + zone;

    auto res = http_client_->get(path);
    std::vector<Lock> locks;

    if (res.ok && res.status == 200)
    {
        std::cout << "[httpGetAllLocks] GET 状态码: " << res.status << std::endl;
        std::cout << "[httpGetAllLocks] GET 响应体: " << res.body << std::endl;

        QByteArray jsonData = QByteArray::fromStdString(res.body);
        QJsonParseError err;
        QJsonDocument doc = QJsonDocument::fromJson(jsonData, &err);
        if (err.error != QJsonParseError::NoError || !doc.isArray())
        {
            std::cerr << "JSON解析失败: " << err.errorString().toStdString() << std::endl;
            return locks;
        }

        QJsonArray arr = doc.array();
        for (const QJsonValue &val : arr)
        {
            if (!val.isObject())
                continue;
            QJsonObject obj = val.toObject();
            Lock lock;
            lock.brand_code = obj.value("brand_code").toString().toStdString();
            lock.cabinet_number = obj.value("cabinet_number").toString().toStdString();
            lock.collect_time = obj.value("collect_time").toString().toStdString();
            lock.controller_id = obj.value("controller_id").toString().toStdString();
            lock.effective_time = obj.value("effective_time").toString().toStdString();
            lock.layer = obj.value("layer").toString().toStdString();
            lock.lock = obj.value("lock").toString().toStdString();
            lock.lock_numble = obj.value("lock_numble").toString().toStdString();
            lock.organization = obj.value("organization").toString().toStdString();
            lock.person = obj.value("person").toString().toStdString();
            lock.phone = obj.value("phone").toString().toStdString();
            lock.status = obj.value("status").toString().toStdString();
            lock.type = obj.value("type").toString().toStdString();
            lock.use_time = obj.value("use_time").toString().toStdString();
            lock.zone = obj.value("zone").toString().toStdString();
            locks.push_back(lock);
        }

        // 写入 lock_list.txt
        QFile file("lock_list.txt");
        if (file.open(QIODevice::WriteOnly | QIODevice::Text))
        {
            QTextStream out(&file);
            for (const auto &lock : locks)
            {
                out << QString::fromStdString(lock.lock) << "\n";
            }
            file.close();
        }
        else
        {
            std::cerr << "无法写入 lock_list.txt 文件！" << std::endl;
        }
    }
    else
    {
        std::cerr << "[httpGetAllLocks] GET 错误: " << res.error << ", 状态码: " << res.status << std::endl;
    }
    return locks;
}



